package gcsms

import (
	"encoding/json"
	"errors"
	"fmt"

	"gitee.com/githubdog/goci/libraries/mylog"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
)

type AliConf struct {
	AccessKeyId     string
	AccessKeySecret string
	RegionId        string
	AliyunHost      string
	SignName        string
	ErrLogDir       string
}

var (
	conf AliConf
)

// api密钥设置: https://ram.console.aliyun.com/manage/ak
// 服务接入点: https://help.aliyun.com/document_detail/419270.html
// api短信文档: https://help.aliyun.com/document_detail/419273.html
func SetSmsConfig(c AliConf) {
	conf = c
}

func newAliCoundClient() (*sdk.Client, error) {
	return sdk.NewClientWithAccessKey(conf.RegionId, conf.AccessKeyId, conf.AccessKeySecret)
}

func newCommonRequest() *requests.CommonRequest {
	request := requests.NewCommonRequest()
	request.Method = "POST"
	request.Scheme = "https"
	request.Domain = conf.AliyunHost
	request.ApiName = "SendSms"
	request.Version = "2017-05-25"
	request.QueryParams["SignName"] = conf.SignName
	return request
}

// SendSmsCodeByAliCloud 发送阿里云验证码短信
func SendSmsCodeByAliCloud(phone, tpCode string, code string) error {
	client, err := newAliCoundClient()
	if err == nil {
		request := newCommonRequest()
		request.QueryParams["PhoneNumbers"] = phone
		request.QueryParams["TemplateCode"] = tpCode
		request.QueryParams["TemplateParam"] = `{"code": "` + code + `"}`
		if res, e := client.ProcessCommonRequest(request); e == nil {
			defer res.GetOriginHttpResponse().Body.Close()
			ret := map[string]string{}
			if err = json.Unmarshal(res.GetHttpContentBytes(), &ret); err == nil {
				if ret["Code"] != "OK" {
					if ret["Message"] == "" {
						ret["Message"] = "sms send fail"
					}
					err = errors.New(ret["Message"])
				}
			}
		} else {
			err = e
		}
	}
	if err != nil && conf.ErrLogDir != "" {
		mylog.WriteLog("sms", "", fmt.Sprintf("[%s] Sms Send Error:", phone), err)
	}
	return err
}

// SendAliCloudSms 发送阿里云短信
func SendAliCloudSms(phone, tpCode string, params map[string]string) error {
	client, err := newAliCoundClient()
	if err == nil {
		request := newCommonRequest()
		request.QueryParams["PhoneNumbers"] = phone
		request.QueryParams["TemplateCode"] = tpCode
		if len(params) > 0 {
			if paramByte, e := json.Marshal(params); e == nil {
				request.QueryParams["TemplateParam"] = string(paramByte)
			} else {
				err = e
			}
		}
		if err == nil {
			if res, e := client.ProcessCommonRequest(request); e == nil {
				defer res.GetOriginHttpResponse().Body.Close()
				ret := map[string]string{}
				if err = json.Unmarshal(res.GetHttpContentBytes(), &ret); err == nil {
					if ret["Code"] != "OK" {
						if ret["Message"] == "" {
							ret["Message"] = "sms send fail"
						}
						err = errors.New(ret["Message"])
					}
				}
			} else {
				err = e
			}
		}
	}
	if err != nil && conf.ErrLogDir != "" {
		mylog.WriteLog("sms", "", fmt.Sprintf("[%s] Sms Send Error:", phone), err)
	}
	return err
}
